package cate.game.res.drop;

import cate.common.annotation.SplitParse;
import cate.common.util.SplitParser;
import cate.common.util.random.RWItem;
import cate.common.util.random.RWList;
import cate.game.res.MixRes;
import cate.game.res.MixResItem;
import cate.game.res.Pair;
import easy.java.dev.note.NoteClass;
import easy.java.dev.note.NoteField;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;

@NoteClass(value = "掉落配置")
public class DropConfig {

    @NoteField(value = "随机抽取次数", detail = "从掉落配置中随机抽取的次数")
    private int drawNum;

    private RWList<Item> rwList = new RWList<>();

    public void parse(String config, int drowNum) {
        if (StringUtils.isBlank(config)) {
            return;
        }
        this.drawNum = drowNum;
        List<Item> list = SplitParser.parse(Item.class, config);
        list.forEach(Item::init);
        rwList.setup(list);
    }

    public static class Item implements RWItem {
        @SplitParse(order = 0, defaultValue = "3", note = "掉落物品的大类型")
        public byte type;

        @SplitParse(order = 1, defaultValue = "-1", note = "掉落物品的模板ID")
        public int templateId;

        @SplitParse(order = 2, defaultValue = "0", note = "掉落物品的数量配置")
        public String numConf;

        @SplitParse(order = 3, defaultValue = "100", note = "权重")
        public double weight;

        public List<Pair<Integer, Double>> numList = new ArrayList<>();

        public void init() {
            String[] optionStrArr = this.numConf.split("&");
            double totalWeight = 0;
            for (String optionStr : optionStrArr) {
                String[] valueArr = optionStr.split("=");
                if (valueArr.length > 0) {
                    int num = Integer.valueOf(valueArr[0]);
                    double weight = 100;
                    if (valueArr.length > 1) {
                        weight = Float.valueOf(valueArr[1]);
                    }
                    totalWeight += weight;
                    numList.add(new Pair<>(num, totalWeight));
                }
            }
            for (Pair<Integer, Double> p : numList) {
                p.v = p.v / totalWeight;
            }
        }

        public int num() {
            if (numList.size() == 0) {
                return 1;
            }
            double random = Math.random();
            for (Pair<Integer, Double> p : numList) {
                if (random <= p.v) {
                    return p.k;
                }
            }
            return -1;
        }

        @Override
        public double getWeight() {
            return weight;
        }
    }

    /** 动态创建物品组 */
    public MixRes buildResList() {
        MixRes r = new MixRes();
        List<Item> theList = new ArrayList<>();
        for (int i = 0; i < drawNum; i++) {
            Item temp = rwList.get();
            if (temp != null){
                theList.add(temp);
            }
        }
        for (Item item : theList) {
            int num = item.num();
            if (num > 0) {
                MixResItem ri = new MixResItem();
                ri.type = item.type;
                ri.tid(item.templateId);
                ri.num = num;
                r.addItem(ri);
            }
        }
        return r;
    }

    /** 动态创建物品组N次 */
    public MixRes buildResList(int times) {
        MixRes r = new MixRes();
        for (int i = 0; i < times; i++) {
            r.addList(this.buildResList());
        }
        return r;
    }
}
